home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / pbmplus / pbm / pbmtog3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  3.8 KB  |  224 lines

  1. /* pbmtog3.c - read a portable bitmap and produce a Group 3 FAX file
  2. **
  3. ** Copyright (C) 1989 by Paul Haeberli <paul@manray.sgi.com>.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include "pbm.h"
  14. #include "g3.h"
  15.  
  16. static void tofax ARGS(( bit* bitrow, int n ));
  17. static void putwhitespan ARGS(( int c ));
  18. static void putblackspan ARGS(( int c ));
  19. static void putcode ARGS(( tableentry* te ));
  20. static void puteol ARGS(( void ));
  21. static void putinit ARGS(( void ));
  22. static void putbit ARGS(( int d ));
  23. static void flushbits ARGS(( void ));
  24.  
  25. static int reversebits;
  26.  
  27. void
  28. main( argc, argv )
  29.     int argc;
  30.     char* argv[];
  31.     {
  32.     FILE* ifp;
  33.     bit* bitrow;
  34.     int argn, rows, cols, bigcols, format, row, col, i;
  35.     char* usage = " [-reversebits] [pbmfile]";
  36.  
  37.     pbm_init( &argc, argv );
  38.  
  39.     argn = 1;
  40.     reversebits = 0;
  41.  
  42.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  43.     {
  44.     if ( pm_keymatch( argv[argn], "-reversebits", 2 ) )
  45.         reversebits = 1;
  46.     else
  47.         pm_usage( usage );
  48.     ++argn;
  49.     }
  50.     
  51.     if ( argn == argc )
  52.     ifp = stdin;
  53.     else
  54.     {
  55.     ifp = pm_openr( argv[argn] );
  56.     ++argn;
  57.     }
  58.     
  59.     if ( argn != argc )
  60.     pm_usage( usage );
  61.  
  62.     pbm_readpbminit( ifp, &cols, &rows, &format );
  63.     bigcols = max( 1728, cols );
  64.     bitrow = pbm_allocrow( bigcols );
  65.  
  66.     /* Write out four extra rows to get things stabilized. */
  67.     putinit();
  68.     for ( col = 0; col < bigcols; ++col )
  69.     bitrow[col] = PBM_WHITE;
  70.     tofax( bitrow, bigcols );
  71.     tofax( bitrow, bigcols );
  72.     tofax( bitrow, bigcols );
  73.     tofax( bitrow, bigcols );
  74.  
  75.     /* Write out bitmap. */
  76.     for ( row = 0; row < rows; ++row )
  77.     {
  78.     pbm_readpbmrow( ifp, bitrow, cols, format );
  79.     for ( col = cols; col < bigcols; ++col )
  80.         bitrow[col] = PBM_WHITE;
  81.     tofax( bitrow, cols );
  82.     }
  83.  
  84.     /* And finish off. */
  85.     for( i = 0; i < 6; ++i )
  86.     puteol( );
  87.     flushbits( );
  88.  
  89.     pm_close( ifp );
  90.  
  91.     exit( 0 );
  92.     }
  93.  
  94. static void
  95. tofax(bitrow,n)
  96.     bit* bitrow;
  97.     int n;
  98. {
  99.     int c;
  100.  
  101.     while(n>0) {
  102.     c = 0;
  103.     while(*bitrow == PBM_WHITE && n>0) {
  104.         ++bitrow;
  105.         ++c;
  106.         --n;
  107.     }
  108.     putwhitespan(c);
  109.     c = 0;
  110.     if(n==0)
  111.         break;
  112.     while(*bitrow == PBM_BLACK && n>0) {
  113.         ++bitrow;
  114.         ++c;
  115.         --n;
  116.     }
  117.     putblackspan(c);
  118.     }
  119.     puteol();
  120. }
  121.  
  122. static void
  123. putwhitespan(c)
  124.     int c;
  125. {
  126.     int tpos;
  127.     tableentry* te;
  128.  
  129.     if(c>=64) {
  130.     tpos = (c/64)-1;
  131.     te = mwtable+tpos;
  132.     c -= te->count;
  133.     putcode(te);
  134.     }
  135.     tpos = c;
  136.     te = twtable+tpos;
  137.     putcode(te);
  138. }
  139.  
  140. static void
  141. putblackspan(c)
  142.     int c;
  143. {
  144.     int tpos;
  145.     tableentry* te;
  146.  
  147.     if(c>=64) {
  148.     tpos = (c/64)-1;
  149.     te = mbtable+tpos;
  150.     c -= te->count;
  151.     putcode(te);
  152.     }
  153.     tpos = c;
  154.     te = tbtable+tpos;
  155.     putcode(te);
  156. }
  157.  
  158. static void
  159. putcode(te)
  160.     tableentry* te;
  161. {
  162.     unsigned int mask;
  163.     int code;
  164.  
  165.     mask = 1<<(te->length-1);
  166.     code = te->code;
  167.     while(mask) {
  168.      if(code&mask)
  169.         putbit(1);
  170.     else
  171.         putbit(0);
  172.     mask >>= 1;
  173.     }
  174.  
  175. }
  176.  
  177. static void
  178. puteol()
  179. {
  180.     int i;
  181.  
  182.     for(i=0; i<11; ++i)
  183.     putbit(0);
  184.     putbit(1);
  185. }
  186.  
  187. static int shdata;
  188. static int shbit;
  189.  
  190. static void
  191. putinit()
  192. {
  193.     shdata = 0;
  194.     shbit = reversebits ? 0x01 : 0x80;
  195. }
  196.  
  197. static void
  198. putbit(d)
  199. int d;
  200. {
  201.     if(d) 
  202.     shdata = shdata|shbit;
  203.     if ( reversebits )
  204.     shbit = shbit<<1;
  205.     else
  206.     shbit = shbit>>1;
  207.     if((shbit&0xff) == 0) {
  208.     putchar(shdata);
  209.     shdata = 0;
  210.     shbit = reversebits ? 0x01 : 0x80;
  211.     }
  212. }
  213.  
  214. static void
  215. flushbits( )
  216. {
  217.     if ( ( reversebits && shbit != 0x01 ) ||
  218.      ( ! reversebits && shbit != 0x80 ) ) {
  219.     putchar(shdata);
  220.     shdata = 0;
  221.     shbit = reversebits ? 0x01 : 0x80;
  222.     }
  223. }
  224.